import java.util.Collection;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

// Tabs = 4
//************************************************************
//	COPYRIGHT 2011 Bread Zeppelin - ALL RIGHTS RESERVED
//
// This file is the product of Bread Zeppelin and cannot be 
// reproduced, copied, or used in any shape or form without 
// the express written consent of Bread Zeppelin.
//************************************************************
//
//	$ID: Concurrent_Assg6
//
//	$Date: Feb 13, 2012
//
//	Reason:
//
//*************************************************************

/** $Author: Ben Hare, Zach Huenink, Philipp Wittmaack, Peter Maresca */
/** $Revision: 1 */

// Default Package

/**
 * HostessExecutor is a fixed thread pool that upon creation takes a number of 
 * max hostesses.
 * @params int maxHostesses = number of max hostesses
 */
public class HostessExecutor extends ThreadPoolExecutor {
	
	private long timeIdle;
	private long startBalance;
	
	HostessExecutor(int maxHostesses){
		super(maxHostesses, maxHostesses, 1000, TimeUnit.NANOSECONDS, new LinkedBlockingQueue<Runnable>());
		timeIdle = 0;
		startBalance = System.currentTimeMillis();
	}
	
	/* (non-Javadoc)
	 * @see java.util.concurrent.Executor#execute(java.lang.Runnable)
	 */
	@Override
	public void execute(Runnable command) {
		super.execute(command);
		if (super.getActiveCount() != super.getMaximumPoolSize()){
			timeIdle = (System.currentTimeMillis()-startBalance)*(super.getMaximumPoolSize()-super.getActiveCount());

			RestaurantMetrics.getInstance().finishHostessTime(command, timeIdle);
		}
	}

	/* (non-Javadoc)
	 * @see java.util.concurrent.ExecutorService#awaitTermination(long, java.util.concurrent.TimeUnit)
	 */
	@Override
	public boolean awaitTermination(long timeout, TimeUnit unit)
			throws InterruptedException {
		return super.awaitTermination(timeout, unit);
	}

	/* (non-Javadoc)
	 * @see java.util.concurrent.ExecutorService#invokeAll(java.util.Collection)
	 */
	@Override
	public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
			throws InterruptedException {
		return super.invokeAll(tasks);
	}

	/* (non-Javadoc)
	 * @see java.util.concurrent.ExecutorService#invokeAll(java.util.Collection, long, java.util.concurrent.TimeUnit)
	 */
	@Override
	public <T> List<Future<T>> invokeAll(
			Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
			throws InterruptedException {
		return super.invokeAll(tasks, timeout, unit);
	}

	/* (non-Javadoc)
	 * @see java.util.concurrent.ExecutorService#invokeAny(java.util.Collection)
	 */
	@Override
	public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
			throws InterruptedException, ExecutionException {
		return super.invokeAny(tasks);
	}

	/* (non-Javadoc)
	 * @see java.util.concurrent.ExecutorService#invokeAny(java.util.Collection, long, java.util.concurrent.TimeUnit)
	 */
	@Override
	public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
			long timeout, TimeUnit unit) throws InterruptedException,
			ExecutionException, TimeoutException {
		return super.invokeAny(tasks, timeout, unit);
	}

	/* (non-Javadoc)
	 * @see java.util.concurrent.ExecutorService#isShutdown()
	 */
	@Override
	public boolean isShutdown() {
		return super.isShutdown();
	}

	/* (non-Javadoc)
	 * @see java.util.concurrent.ExecutorService#isTerminated()
	 */
	@Override
	public boolean isTerminated() {
		return super.isTerminated();
	}

	/* (non-Javadoc)
	 * @see java.util.concurrent.ExecutorService#shutdown()
	 */
	@Override
	public void shutdown() {
		super.shutdown();
	}

	/* (non-Javadoc)
	 * @see java.util.concurrent.ExecutorService#shutdownNow()
	 */
	@Override
	public List<Runnable> shutdownNow() {
		return super.shutdownNow();
	}

	/* (non-Javadoc)
	 * @see java.util.concurrent.ExecutorService#submit(java.util.concurrent.Callable)
	 */
	@Override
	public <T> Future<T> submit(Callable<T> task) {
		return super.submit(task);
	}

	/* (non-Javadoc)
	 * @see java.util.concurrent.ExecutorService#submit(java.lang.Runnable)
	 */
	@Override
	public Future<?> submit(Runnable task) {
		return super.submit(task);
	}

	/* (non-Javadoc)
	 * @see java.util.concurrent.ExecutorService#submit(java.lang.Runnable, java.lang.Object)
	 */
	@Override
	public <T> Future<T> submit(Runnable task, T result) {
		return super.submit(task, result);
	}
}
